package model

import (
	"github.com/tianjigames/fairy/constants"
	"github.com/tianjigames/fairy/template"
	"github.com/tianjigames/fairy/util"
	"github.com/topfreegames/pitaya/logger"
)



type (
	CommonItem struct {
		MItemCfg           *template.Item
		MVersion           byte
		ItemGuid           int64
		Valid              byte
		TemplateId         int
		StackCount         int
		ProTime            int64
		UseTime            int64
		ItemState          byte
		GemIndex           byte
		StrengthLevel      int
		StrengthCurrentExp int
		StartLevel         int
		RandAttrCount      byte
		RandAttrType       []byte
		RandAttrCal        []byte
		RandAttrValue      []int
		RandAttrQuality    []byte
		WashTimes          int
		DeleteState        byte
	}
)

func GetVirtualTypeByValue(val int) *constants.VirtualType {
	if val < int(constants.VirtualTypeInvalid) || val > int(constants.VirtualTypeMaxValue) {
		return nil
	}

	rt := constants.VirtualType(val)
	return &rt

}

/**
判断物品是否有效
 */
func (p *CommonItem) IsValid() bool {
	return p.Valid > 0
}

func (p *CommonItem) GetId() int {
	return p.TemplateId
}

func NewCommonItem() *CommonItem {
	return &CommonItem{
		RandAttrType: make([]byte,constants.EquipRandAttrCount),
		RandAttrCal: make([]byte,constants.EquipRandAttrCount),
		RandAttrValue: make([]int,constants.EquipRandAttrCount),
		RandAttrQuality: make([]byte,constants.EquipRandAttrCount),
	}
}

func (p *CommonItem) ReadObject(in []byte,startIdx int) int {
	nBeginIdx := startIdx
	switch p.MVersion {
	case 1:
		p.ItemGuid = util.ByteArrayToInt64(in,nBeginIdx)
		nBeginIdx += 8

		p.Valid = in[nBeginIdx]
		nBeginIdx += 1

		p.TemplateId = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4

		p.StackCount = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4

		p.ProTime = util.ByteArrayToInt64(in,nBeginIdx)
		nBeginIdx += 8

		p.UseTime = util.ByteArrayToInt64(in,nBeginIdx)
		nBeginIdx += 8

		p.ItemState = in[nBeginIdx]
		nBeginIdx += 1

		p.GemIndex = in[nBeginIdx]
		nBeginIdx += 1

		p.StrengthLevel = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4

		p.StrengthCurrentExp = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4

		p.StartLevel = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4

		p.RandAttrCount = in[nBeginIdx]
		nBeginIdx += 1

		//随机属性类型
		for i:=0;i<constants.EquipRandAttrCount;i++ {
			p.RandAttrType[i] = in[nBeginIdx]
			nBeginIdx += 1
		}

		//随机属性加成方式
		for i :=0;i<constants.EquipRandAttrCount;i++ {
			p.RandAttrCal[i] = in[nBeginIdx]
			nBeginIdx +=1
		}

		//随机属性加成值
		for i := 0;i<constants.EquipRandAttrCount;i++ {
			p.RandAttrValue[i] = util.ByteArrayToInt(in,nBeginIdx)
			nBeginIdx += 4
		}

		for i:=0;i<constants.EquipRandAttrCount;i++ {
			p.RandAttrQuality[i] = in[nBeginIdx]
			nBeginIdx += 1
		}

		p.WashTimes = util.ByteArrayToInt(in,nBeginIdx)
		nBeginIdx += 4
	}
	return nBeginIdx -startIdx
}

/**
初始化数据
 */
func (p *CommonItem) InitData(cfg *template.Item)  {
	p.MItemCfg = cfg
	p.Valid = constants.StateTrue
}

/**
修复叠加数量
 */
func (p *CommonItem) RepairStackCount()  {
	if p.StackCount <=  0 {
		logger.Log.Errorf("CommonItem :: stackCountIllegal id:%d guid:%d count:%d",
			p.TemplateId,p.ItemGuid,p.StackCount)
	}else if p.MItemCfg != nil && p.MItemCfg.Composition > 0 && p.StackCount > p.MItemCfg.Composition {
		logger.Log.Errorf("CommonItem :: stackCountIllegal id:%d guid:%d count:%d max:%d",
			p.TemplateId,p.ItemGuid,p.StackCount,p.MItemCfg.Composition)
		p.StackCount = p.MItemCfg.Composition
	}
}

/**
判断物品是否可以穿在身上
 */
func (p *CommonItem) IsBody() bool {
	return p.GetState(constants.ItemStateBody) == constants.StateTrue
}

/**
设置装备穿在身上的状态
 */
func (p *CommonItem) SetBody(state byte)  {
	p.SetState(constants.ItemStateBody,state)
}

/**
判断是否为仓库中的物品
 */
func (p *CommonItem) IsStore() bool {
	return p.GetState(constants.ItemStateStore) == constants.StateTrue
}

/**
获取状态值
 */
func (p *CommonItem) GetState(stateIdx byte) byte {
	if stateIdx < 0 || stateIdx >= 8 {
		return 0
	}

	return (p.ItemState >> stateIdx) & 0x01
}

func (p *CommonItem) SetBind(state byte)  {
	p.SetState(constants.ItemStateBind,state)
}

func (p *CommonItem) IsBind() bool {
	return p.GetState(constants.ItemStateBind) == constants.StateTrue
}

func (p *CommonItem) SetState(stateIdx,flag byte)  {
	if stateIdx < 0 || stateIdx >= 8 {
		return
	}

	if flag == constants.StateTrue {
		p.ItemState |= 0x01 << stateIdx
	}else if flag == constants.StateFalse{
		p.ItemState &= ^(0x01 << stateIdx)
	}
}
